<template>
  <div class="container">
    <a-card class="general-card" :title="$route.meta.locale">
      <table-search
        v-permission="'system:menu:query'"
        :fileds="searchFileds"
        @search="search"
        @reset="search"
      ></table-search>
      <xTable
        v-model:refresh="refresh"
        v-model:selected-keys="selectedKeys"
        :params="params"
        :columns="tableColumns"
        :http="{
          list: getListData,
          del: delMenu,
        }"
        :http-permission="{
          del: 'system:menu:remove',
          batchDel: '',
        }"
        http-data-key="data"
        :format-data="formatTableData"
      >
        <template #operation-default>
          <div v-permission="'system:menu:add'" class="item">
            <a-button type="outline" @click="editOpen(null)"> 新增 </a-button>
          </div>
          <div v-permission="'system:menu:edit'" class="item">
            <a-button
              type="outline"
              status="success"
              @click="editOpen(selectedKeys)"
            >
              编辑
            </a-button>
          </div>
        </template>
        <template #status="{ row }">
          <dict-tag :options="dict.sys_normal_disable" :value="row.status" />
        </template>
        <template #optional="{ row }">
          <a-button
            v-permission="'system:menu:edit'"
            type="text"
            status="success"
            @click="editOpen(row.menuId)"
          >
            编辑
          </a-button>
        </template>
      </xTable>
    </a-card>
    <EditModal
      ref="edit"
      :default-value="{ orderNum: 0, menuType: 'M', status: defaultStatus }"
      :fields="editFields"
      :http-add="addMenu"
      :http-edit="updateMenu"
      :http-get="getMenu"
      :get-handler="getHandler"
      @reload="refresh = true"
    >
    </EditModal>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, ref, computed, toRaw } from 'vue';
  import { addDateRange, listToTree } from '@/utils/index';
  import {
    getListData,
    getMenu,
    addMenu,
    updateMenu,
    delMenu,
  } from '@/api/system/menu';
  import { getDict } from '@/utils/dict';
  import { Message } from '@arco-design/web-vue';
  import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';

  const menuTree: any = ref([]);
  const initMenuTree = async () => {
    const { code, msg, data } = await getListData({
      deptName: '',
      status: '',
    });
    if (code !== 200) {
      Message.error(msg);
    }
    menuTree.value = listToTree(
      data.map(
        (item: {
          icon: any;
          menuName: any;
          parentId: number;
          menuId: number;
        }) => ({
          ...item,
          icon: null,
          menuIcon: item.icon,
          parentId: item.parentId === 0 ? null : item.parentId,
          id: item.menuId,
          key: item.menuId,
          title: item.menuName,
        })
      ),
      'menuId',
      'parentId'
    );
  };
  const dict = getDict('sys_normal_disable', 'sys_show_hide');
  const edit = ref();
  const selectedKeys = ref([]);

  // 定义查询字段
  const searchFileds: Array<any> = reactive([
    {
      span: 5,
      field: 'deptName',
      placeholder: '请输入菜单名称',
      label: '菜单名称',
      tag: 'a-input',
      initValue: '',
    },
    {
      span: 5,
      field: 'status',
      placeholder: '请选择状态',
      label: '状态',
      initValue: '',
      tag: 'a-select',
      attrs: {
        options: [
          { value: '1', label: '通知' },
          { value: '2', label: '公告' },
        ],
      },
    },
  ]);
  // 定义表格字段
  const tableColumns: Array<TableColumnData> = reactive([
    {
      dataIndex: 'menuName',
      title: '菜单名称',
    },
    // {
    //   dataIndex: 'icon',
    //   title: '图标',
    // },
    {
      dataIndex: 'orderNum',
      title: '排序',
    },
    {
      dataIndex: 'perms',
      title: '权限标识',
    },
    {
      dataIndex: 'component',
      title: '组件路径',
    },
    {
      dataIndex: 'status',
      title: '状态',
      slotName: 'status',
    },
    {
      dataIndex: 'createTime',
      title: '创建时间',
    },
    {
      dataIndex: 'optional',
      title: '操作',
      slotName: 'optional',
    },
  ]);

  const editFields: Array<any> = reactive([
    {
      key: 'parentId',
      label: '上级菜单',
      placeholder: '请选择上级菜单',
      tag: 'a-tree-select',
      span: 24,
      attrs: {
        'data': menuTree,
        'treeProps': {
          virtualListProps: {
            height: 200,
          },
        },
        'allow-search': true,
        'allow-clear': true,
        'filter-tree-node': (
          searchValue: string,
          nodeData: { title: string }
        ) => {
          return (
            String(nodeData.title)
              .toLowerCase()
              .indexOf(String(searchValue).toLowerCase()) > -1
          );
        },
      },
      decorator: {
        rules: [{ required: false, message: '请选择上级菜单' }],
      },
    },
    {
      key: 'menuType',
      label: '菜单类型',
      placeholder: '请选择菜单类型',
      tag: 'a-radio-group',
      attrs: {
        options: [
          { value: 'M', label: '目录' },
          { value: 'C', label: '菜单' },
          { value: 'F', label: '按钮' },
        ],
      },
      decorator: {
        rules: [{ required: false, message: '请选择菜单类型' }],
      },
    },
    // icon
    // show: (value: any) => {
    //     return value.menuType === 'C';
    //   },
    {
      key: 'menuName',
      label: '菜单名称',
      placeholder: '请输入菜单名称',
      tag: 'a-input',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      attrs: {},
      decorator: {
        rules: [{ required: true, message: '请输入菜单名称' }],
      },
    },
    {
      key: 'orderNum',
      label: '显示排序',
      placeholder: '请输入显示排序',
      tag: 'a-input-number',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      attrs: {},
      decorator: {
        rules: [{ required: true, message: '请输入显示排序' }],
      },
    },
    {
      key: 'isFrame',
      label: '是否外链',
      placeholder: '请选择是否外链',
      tag: 'a-radio-group',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      attrs: {
        options: [
          { value: '0', label: '是' },
          { value: '1', label: '否' },
        ],
      },
      show: (value: any) => {
        return value.menuType !== 'F';
      },
      decorator: {
        rules: [{ required: false, message: '请选择是否外链' }],
      },
    },
    {
      key: 'path',
      label: '路由地址',
      placeholder: '请输入路由地址',
      tag: 'a-input',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      show: (value: any) => {
        return value.menuType !== 'F';
      },
      decorator: {
        rules: [{ required: true, message: '请输入路由地址' }],
      },
    },
    {
      key: 'component',
      label: '组件路径',
      placeholder: '请输入组件路径',
      tag: 'a-input',
      span: 12,
      show: (value: any) => {
        return value.menuType === 'C';
      },
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      decorator: {
        rules: [{ required: false, message: '请输入组件路径' }],
      },
    },
    {
      key: 'perms',
      label: '权限字符',
      placeholder: '请输入权限字符',
      tag: 'a-input',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      show: (value: any) => {
        return value.menuType !== 'M';
      },
      decorator: {
        rules: [{ required: false, message: '请输入权限字符' }],
      },
    },
    {
      key: 'query',
      label: '路由参数',
      placeholder: '请输入路由参数',
      tag: 'a-input',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      show: (value: any) => {
        return value.menuType === 'C';
      },
      decorator: {
        rules: [{ required: false, message: '请输入路由参数' }],
      },
    },
    {
      key: 'isCache',
      label: '是否缓存',
      placeholder: '请输入是否缓存',
      tag: 'a-radio-group',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      attrs: {
        options: [
          { value: '0', label: '缓存' },
          { value: '1', label: '不缓存' },
        ],
      },
      show: (value: any) => {
        return value.menuType === 'C';
      },
      decorator: {
        rules: [{ required: false, message: '请输入是否缓存' }],
      },
    },
    {
      key: 'visible',
      label: '显示状态',
      placeholder: '请选择显示状态',
      tag: 'a-radio-group',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      attrs: {
        options: dict.sys_show_hide,
      },
      show: (value: any) => {
        return value.menuType !== 'F';
      },
      decorator: {
        rules: [{ required: false, message: '请选择显示状态' }],
      },
    },
    {
      key: 'status',
      label: '菜单状态',
      placeholder: '请选择菜单状态',
      tag: 'a-radio-group',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 14 },
      },
      attrs: {
        options: dict.sys_normal_disable,
      },
      show: (value: any) => {
        return value.menuType !== 'F';
      },
      decorator: {
        rules: [{ required: false, message: '请选择菜单状态' }],
      },
    },
  ]);
  const refresh = ref(true);
  // 定义表格查询参数
  const params = ref({
    dateRange: [],
  });
  // 定义搜索方法
  const search = (data: any) => {
    params.value = addDateRange(data, data?.dateRange);
    refresh.value = true;
  };
  const formatTableData = (data: any) => {
    const datas = listToTree(
      data.map((item: { menuName: any; parentId: number; menuId: number }) => ({
        ...item,
        parentId: item.parentId === 0 ? null : item.parentId,
        id: item.menuId,
        key: item.menuId,
        label: item.menuName,
      })),
      'menuId',
      'parentId'
    );
    return datas;
  };
  const defaultStatus = computed(() => {
    if (dict.sys_normal_disable.value <= 0) {
      return '0';
    }
    const list = toRaw(dict.sys_normal_disable);
    return list.value.find((item: { default: any }) => item.default).value;
  });
  const editOpen = async (keys: any | any[]) => {
    await initMenuTree();
    if (Array.isArray(keys) && keys.length === 1) {
      edit.value.show(keys[0]);
    } else if (!Array.isArray(keys)) {
      edit.value.show(keys);
    } else if (Array.isArray(keys) && keys.length < 1) {
      Message.warning('必须选中一条数据');
    } else if (Array.isArray(keys) && keys.length > 1) {
      Message.warning('只能选中一条数据');
    }
  };
  const getHandler = ({ data }: { [x: string]: any }) => {
    return {
      ...data,
      orderNum: Number(data?.orderNum),
    };
  };
</script>

<style scoped lang="less">
  .operation-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin-bottom: 20px;
    .item {
      margin-left: 8px;
    }
  }
  .container {
    // padding: 0 20px 20px 20px;
  }
  :deep(.arco-table-th) {
    &:last-child {
      .arco-table-th-item-title {
        margin-left: 16px;
      }
    }
  }
</style>
